FullConnection

全连接(矩阵乘融合偏置与激活)。对输入 A 与权重 B 做矩阵乘,可选叠加 bias,再按 activation_type 做逐元素激活,结果写入 C

设有效乘积矩阵为 \(A_{\mathrm{eff}}\)\(B_{\mathrm{eff}}\),形状分别为 \(M \times K\)\(K \times N\),则:

\[C_{i,j} = \operatorname{act}\!\left( \sum_{k=0}^{K-1} (A_{\mathrm{eff}})_{i,k}\,(B_{\mathrm{eff}})_{k,j} + b_{i,j} \right)\]

转置约定(行优先存储;由 paramsA_transposeB_transpose 控制,取值 0 或 1):

  • A_transpose = 0A 形状 \(M \times K\)\((A_{\mathrm{eff}})_{i,k} = A_{i\cdot K+k}\)

  • A_transpose = 1A 形状 \(K \times M\)\((A_{\mathrm{eff}})_{i,k} = A_{k\cdot M+i}\)

  • B_transpose = 0B 形状 \(K \times N\)\((B_{\mathrm{eff}})_{k,j} = B_{k\cdot N+j}\)

  • B_transpose = 1B 形状 \(N \times K\)\((B_{\mathrm{eff}})_{k,j} = B_{j\cdot K+k}\)

偏置(biasNULL\(b_{i,j} = 0\)):

  • bias_broadcast = 0bias 形状 \(M \times N\)\(b_{i,j} = \mathrm{bias}_{i\cdot N+j}\)

  • bias_broadcast = 1bias 形状 \(N\),沿行广播,\(b_{i,j} = \mathrm{bias}_{j}\)

激活(activation_type):

  • 0:恒等,\(\operatorname{act}(x)=x\)

  • 1:ReLU,\(\operatorname{act}(x)=\max(0,x)\)

  • 2:ReLU6,\(\operatorname{act}(x)=\min(\max(0,x), 6)\)

输入:
  • A - 输入矩阵地址

  • B - 权重矩阵地址

  • bias - 偏置地址;无偏置时传 NULL

  • params - long long 参数数组,长度至少 7,布局见下

  • core_mask - 核掩码(仅共享存储版本使用)

params 布局:

  • [0] M - 输出行数

  • [1] N - 输出列数

  • [2] K - 归约维长度

  • [3] activation_type - 激活类型,取值 {0,1,2}

  • [4] A_transpose - 是否按转置语义读 A,取值 {0,1}

  • [5] B_transpose - 是否按转置语义读 B,取值 {0,1}

  • [6] bias_broadcast - 偏置是否按列广播,取值 {0,1}

输出:
  • C - 输出矩阵地址,形状 \(M \times N\)

支持平台:

FT78NE MT7004

备注

  • FT78NE 支持 int8、fp32

  • MT7004 支持 fp16、fp32

  • 本 DSP 接口的激活枚举为 0/1/2``(NONE / ReLU / ReLU6),与 schema ``ActivationType 数值不完全相同

共享存储版本:

void i8_full_connection_s(int8_t *A, int8_t *B, int8_t *C, int8_t *bias, long long *params, int core_mask)
void hp_full_connection_s(float16 *A, float16 *B, float16 *C, float16 *bias, long long *params, int core_mask)
void fp_full_connection_s(float *A, float *B, float *C, float *bias, long long *params, int core_mask)

C调用示例:

 1// MT7004 示例(共享存储多核,DDR 地址)
 2void TestFullConnectionSMCFp32(int core_mask) {
 3    int core_id = get_core_id();
 4    int logic_core_id = GetLogicCoreId(core_mask, core_id);
 5    int core_num = GetCoreNum(core_mask);
 6    float *A = (float *)0x81000000;
 7    float *B = (float *)0x82000000;
 8    float *C = (float *)0x85000000;
 9    long long params[7];
10    params[0] = 16; // M
11    params[1] = 16; // N
12    params[2] = 16; // K
13    params[3] = 1;  // ACTIVATION_RELU
14    params[4] = 0;  // A_transpose
15    params[5] = 0;  // B_transpose
16    params[6] = 1;  // bias_broadcast
17    sys_bar(0, core_num);
18    fp_full_connection_s(A, B, C, NULL, params, core_mask);
19}
20
21void main() {
22    int core_mask = 0b1111;
23    TestFullConnectionSMCFp32(core_mask);
24}

私有存储版本:

void i8_full_connection_p(int8_t *A, int8_t *B, int8_t *C, int8_t *bias, long long *params)
void hp_full_connection_p(float16 *A, float16 *B, float16 *C, float16 *bias, long long *params)
void fp_full_connection_p(float *A, float *B, float *C, float *bias, long long *params)

C调用示例:

 1// MT7004 示例(私有存储单核,AM 地址)
 2void TestFullConnectionAMFp32(void) {
 3    float *A = (float *)0x10010000;
 4    float *B = (float *)0x10020000;
 5    float *C = (float *)0x10050000;
 6    long long params[7];
 7    params[0] = 16; // M
 8    params[1] = 16; // N
 9    params[2] = 16; // K
10    params[3] = 1;  // ACTIVATION_RELU
11    params[4] = 0;  // A_transpose
12    params[5] = 0;  // B_transpose
13    params[6] = 1;  // bias_broadcast
14    fp_full_connection_p(A, B, C, NULL, params);
15}
16
17void main() {
18    TestFullConnectionAMFp32();
19}